package pl.factat.gfk.Display;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.File;

/**
 * Created with IntelliJ IDEA.
 * User: adam
 * Date: 14.12.12
 * Time: 16:27
 * To change this template use File | Settings | File Templates.
 */
public class ImagePanel extends JPanel {
    private BufferedImage image = null;

    private boolean drawPerspectiveFrame = false;
    private final int circleSize = 10;
    private final int filledSize = 3;
    private DraggableCircle[] perspectiveFrameCircles;
    private int mvX = 0;
    private int mvY = 0;
    private int actualCircleIndex = -1;

    public ImagePanel() {
        setBackground(Color.black);
        this.addMouseMotionListener(new MouseMotionListener() {
            @Override
            public void mouseDragged(MouseEvent e) {
                if(actualCircleIndex != -1) {
                    perspectiveFrameCircles[actualCircleIndex].setX(e.getX());
                    perspectiveFrameCircles[actualCircleIndex].setY(e.getY());
                    repaint();
                }
            }

            @Override
            public void mouseMoved(MouseEvent e) {
            }
        });
        this.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                //To change body of implemented methods use File | Settings | File Templates.
            }

            @Override
            public void mousePressed(MouseEvent e) {
                if(actualCircleIndex == -1) {
                    for(int i=0; i< perspectiveFrameCircles.length; ++i)
                    {
                        if(perspectiveFrameCircles[i].isOnCircle(e.getX(), e.getY()))
                        {
                            perspectiveFrameCircles[i].setX(e.getX());
                            perspectiveFrameCircles[i].setY(e.getY());
                            actualCircleIndex = i;
                            repaint();
                            return;
                        }
                    }
                }
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                actualCircleIndex = -1;
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                //To change body of implemented methods use File | Settings | File Templates.
            }

            @Override
            public void mouseExited(MouseEvent e) {
                //To change body of implemented methods use File | Settings | File Templates.
            }
        });
    }

    public void setImage(String f) {

        try {
            image = ImageIO.read(new File(f));
            //System.out.println("setting image");
            setPreferredSize(new Dimension(image.getWidth(), image.getHeight()));
            repaint();
        } catch (Exception e) {
            e.printStackTrace();
        }
        drawPerspectiveFrame();
    }

    public void setImage(BufferedImage img) {
        if(img == null) return;
        this.image = img;
        setPreferredSize(new Dimension(image.getWidth(), image.getHeight()));

        repaint();
    }

    public BufferedImage getImage() {
        return image;
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        if (image != null) {
            try {
                g2d = (Graphics2D) g;
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                g2d.drawImage(image, 0, 0, null);
            } catch (Exception e) {
                JOptionPane.showMessageDialog(this, "Could not load image ");
            }
            if(drawPerspectiveFrame)
            {
                g2d.setColor(new Color(99, 131, 255));
                for(DraggableCircle c : perspectiveFrameCircles)
                {
                    c.draw(g2d);
                }
                g2d.drawLine(perspectiveFrameCircles[0].getX()+circleSize/2, perspectiveFrameCircles[0].getY()+circleSize/2, perspectiveFrameCircles[1].getX()+circleSize/2, perspectiveFrameCircles[1].getY()+circleSize/2);
                g2d.drawLine(perspectiveFrameCircles[0].getX()+circleSize/2, perspectiveFrameCircles[0].getY()+circleSize/2, perspectiveFrameCircles[3].getX()+circleSize/2, perspectiveFrameCircles[3].getY()+circleSize/2);
                g2d.drawLine(perspectiveFrameCircles[2].getX()+circleSize/2, perspectiveFrameCircles[2].getY()+circleSize/2, perspectiveFrameCircles[3].getX()+circleSize/2, perspectiveFrameCircles[3].getY()+circleSize/2);
                g2d.drawLine(perspectiveFrameCircles[2].getX()+circleSize/2, perspectiveFrameCircles[2].getY()+circleSize/2, perspectiveFrameCircles[1].getX()+circleSize/2, perspectiveFrameCircles[1].getY()+circleSize/2);
                g2d.drawLine(perspectiveFrameCircles[0].getX()+circleSize/2, perspectiveFrameCircles[0].getY()+circleSize/2, perspectiveFrameCircles[2].getX()+circleSize/2, perspectiveFrameCircles[2].getY()+circleSize/2);
                g2d.drawLine(perspectiveFrameCircles[1].getX()+circleSize/2, perspectiveFrameCircles[1].getY()+circleSize/2, perspectiveFrameCircles[3].getX()+circleSize/2, perspectiveFrameCircles[3].getY()+circleSize/2);
            }
        }
    }

    public int[] getImageData() {
        return ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
    }

    public int[] getPerspectiveCorners()
    {
        int[] tmp = new int[8];
        for(int i=0; i< perspectiveFrameCircles.length; ++i)
        {
            tmp[i*2] = perspectiveFrameCircles[i].getX();
            tmp[i*2 + 1] = perspectiveFrameCircles[i].getY();
        }
        return tmp;
    }
    private void drawPerspectiveFrame()
    {
        perspectiveFrameCircles = new DraggableCircle[4];
        perspectiveFrameCircles[0] = new DraggableCircle(-circleSize/2,-circleSize/2,circleSize);
        //g2d.drawOval(0, 0, circleSize, circleSize);
        perspectiveFrameCircles[1] = new DraggableCircle(image.getWidth() - circleSize/2, -circleSize/2, circleSize);
        //g2d.drawOval(image.getWidth() - circleSize, 0, circleSize, circleSize);
        perspectiveFrameCircles[2] = new DraggableCircle(image.getWidth() - circleSize, image.getHeight() - circleSize, circleSize);
        //g2d.drawOval(image.getWidth() - circleSize, image.getHeight() - circleSize, circleSize, circleSize);
        perspectiveFrameCircles[3] = new DraggableCircle(-circleSize/2, image.getHeight() - circleSize, circleSize);
        //g2d.drawOval(0, image.getHeight() - circleSize, circleSize, circleSize);

    }
    public void setDrawPerspectiveFrame(boolean b)
    {
        this.drawPerspectiveFrame = b;
        if(drawPerspectiveFrame) drawPerspectiveFrame();
        repaint();
    }
}